<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of DevolucionesManager
 *
 */
class DevolucionesManager {

    //$carro["producto"] => DetalleVentas
    //$carro["cantidad"]   => cantidad
    //$carro["descripcion"]   => descripcion
    //$carro["cantidad_devuelta"] = cantDevuelta

    private static $instancia;
    private $iva;

    const CANT_MINIMA=1;

    static public function getInstance() {
        if (!self::$instancia instanceof self) {
            self::$instancia = new self;
        }
        return self::$instancia;
    }

    public function __construct() {

    }

    public function cargarDevolucion(DetalleVentas $detalle, $cantidad=1) {

        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');
        $prodVacio = 0;
        if (!empty($detalle)) {
            $articulo = $detalle->getDetVtaArticulo();
            $talle = $detalle->getDetVtaTalle();
            $ganancia = $detalle->getDetVtaGanancia();
            $cant_devuelta = $detalle->getCantidadDevuelta();
            $producto = ProductosPeer::retrieveByPK($articulo, $talle);

            if (!empty($producto)) {
                $carro[$articulo . '.' . $talle]["producto"] = $detalle;

                if (!empty($carro[$articulo . '.' . $talle]["cantidad"])) {
                    $cantCarro = $carro[$articulo . '.' . $talle]["cantidad"];
                    $cantCarro = $cantCarro + $cantidad;
                    $carro[$articulo . '.' . $talle]["cantidad"] = $cantCarro;
                    $carro[$articulo . '.' . $talle]["descripcion"] = $producto->getProDescripcion();
                    $carro[$articulo . '.' . $talle]["cantidad_devuelta_total"] = $cant_devuelta;
                    $carro[$articulo . '.' . $talle]["cantidad_devuelta"] = $prodVacio;
                } else {
                    $carro[$articulo . '.' . $talle]["cantidad"] = $cantidad;
                    $carro[$articulo . '.' . $talle]["descripcion"] = $producto->getProDescripcion();
                    $carro[$articulo . '.' . $talle]["cantidad_devuelta_total"] = $cant_devuelta;
                    $carro[$articulo . '.' . $talle]["cantidad_devuelta"] = $prodVacio;
                }

                sfContext::getInstance()->getUser()->setAttribute('devolucion', $carro);

                return true;
            } else {
                $carro[$articulo . '.' . $talle]["cantidad"] = $cantidad;
            }
        }

        sfContext::getInstance()->getUser()->setAttribute('devolucion', $carro);

        return false;
    }

    public function devolverTodos($producto) {

        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        if (!empty($carro)) {
            if (!empty($producto)) {
                $indice = $this->productoExiste($producto);

                if ($indice != false) {

                    $cantDevuelta = $carro[$indice]["cantidad_devuelta"];
                    $cant = $carro[$indice]["cantidad"];

                    if ($cantDevuelta != $cant) {

                        $cantDevuelta = $cant;
                        $carro[$indice]["cantidad_devuelta"] = $cantDevuelta;
                        sfContext::getInstance()->getUser()->setAttribute('devolucion', $carro);
                        return true;
                    }
                }
            }
        }

        return false;
    }

    public function productoExiste(DetalleVentas $detalle) {

        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        if (!empty($carro)) {

            $art = $detalle->getDetVtaArticulo();
            $talle = $detalle->getDetVtaTalle();
            $existe = false;
            foreach ($carro as $i => $detalle) {

                if (($detalle["producto"]->getDetVtaArticulo() == $art) && ($detalle["producto"]->getDetVtaTalle() == $talle)) {
                    $indice = $i;
                    $talle = $i["talle"];
                    $articulo = $i["articulo"];
                    $existe = true;
                }
            }

            if ($existe == true) {
                /* $indice["articulo"] = $articulo;
                  $indice["talle"] = $talle;
                  var_dump($indice);exit(); */
                return $indice;
            }
        }
        return false;
    }

    public function recuperarProducto(DetalleVentas $detalle) {

        $cantidad = self::CANT_MINIMA;
        $cantNula = 0;
        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        if (!empty($carro)) {

            if (!empty($detalle)) {

                $indice = $this->productoExiste($detalle);

                $cantDevueltaTotal = $carro[$indice]["cantidad_devuelta_total"];
                $cantDevuelta = $carro[$indice]["cantidad_devuelta"];
                $cant = $carro[$indice]["cantidad"];
                $cant_max_a_devolver = $cant - $cantDevuelta;
                if ($cant_max_a_devolver < $cant ) {
                    if ($indice != false) {

                        $cantDevuelta -= $cantidad;
                        $carro[$indice]["cantidad_devuelta_total"]--;
                        $carro[$indice]["cantidad_devuelta"]--;
                        $carro[$indice]["cantidad"];
                        sfContext::getInstance()->getUser()->setAttribute('devolucion', $carro);
                        return true;
                    }
                }
            }
            return false;
        }
    }

    public function devolverCantProducto(DetalleVentas $detalle) {

        $cantidad = self::CANT_MINIMA;
        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        if (!empty($carro)) {
            if (!empty($detalle)) {

                $indice = $this->productoExiste($detalle);

                if ($indice != false) {

                    $cantDevuelta = $carro[$indice]["cantidad_devuelta"];
                    $cantDevueltaTotal = $carro[$indice]["cantidad_devuelta_total"];
                    $cant = $carro[$indice]["cantidad"];

                    if ($cantDevueltaTotal < $cant) {
                        $cantDevuelta += $cantidad;
                        $carro[$indice]["cantidad_devuelta"] = $cantDevuelta;
                        $carro[$indice]["cantidad_devuelta_total"]++;

                    }
                }
                sfContext::getInstance()->getUser()->setAttribute('devolucion', $carro);
                return true;
            }
        }
        return false;
    }

    public function checkOut($vtaId) {
        $con = Propel::getConnection();
        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');
        try {
            //abrimos la transacción
            $con->beginTransaction();

            $venta = VentasPeer::retrieveByPK($vtaId);
            if (!empty($venta)) {

                if ($venta->esCondicional()) {
                    //Venta condicional
                    //borrar detalle venta
                    //DetalleVentasPeer::BorrarDetalleDeVenta($vtaId);
                    $totalDevolucion = $this->getTotalDevolucion();
                    $nroNotaCredito = $this->autogenerarNroNotaDeCredito();
                    //crear devolucion
                    $devolucion = new Devoluciones();
                    $devolucion->setDevFecha(time());
                    $devolucion->setDevPrecio($totalDevolucion);
                    $devolucion->setDevNroNotaCredito($nroNotaCredito);
                    $devolucion->setDevVenta($vtaId);
                    $devolucion->save();

                    //setear productos devueltos y actualizar detalle venta
                    foreach ($carro as $detalle) {
                        $cantDevuelta = $detalle["cantidad_devuelta"];
                        $cantVenta = $detalle["cantidad"];
                        $prod = $detalle["producto"];
                        if (!empty($cantDevuelta)) {

                            //Generar nuevo detalle de devolucion
                            $ultimaDevolucion = DevolucionesPeer::obtenerUltimaDevolucion();

                            $detalleDevolucion = new DetalleDevoluciones();
                            $detalleDevolucion->setDetDevDevolucion($ultimaDevolucion->getDevId());
                            $detalleDevolucion->setDetVtaArticulo($prod->getDetVtaArticulo());
                            $detalleDevolucion->setDetVtaTalle($prod->getDetVtaTalle());
                            $detalleDevolucion->setDetVtaCantidad($cantDevuelta);
                            $detalleDevolucion->save();

                            //Actualizar Disponibilidad de producto
                            $producto = ProductosPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle());
                            $cantActualProducto = $producto->getProCantidad();
                            $dispActualProducto = $producto->getProDisponible();
                            $producto->setProCantidad($cantActualProducto + $cantDevuelta);
                            $producto->setProDisponible($dispActualProducto + $cantDevuelta);
                            $producto->save();
                        }
                        $detalleVentaOriginal = DetalleVentasPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle(), $vtaId);
                        $cant = $detalleVentaOriginal->getDetVtaCantidad();
                        if ($cantDevuelta != $cantVenta) {
                            $detalleVentaOriginal->setDetVtaCantidad($cant - $cantDevuelta);
                        } else {
                            $detalleVentaOriginal->delete();
                        }
                    }

                    //Devolucion Parcial
                    if ($this->esDevolucionParcial()) {

                        $venta->setVtaTipo(sfconfig::get('app_venta_tipo_condicional'));
                        $venta->save();

                        //Nueva Venta Definitiva con los productos que queden
                        //Nueva Venta
                        $newVenta = new Ventas();
                        $newVenta->setVtaIva(sfConfig::get('app_iva'));
                        $newVenta->setVtaNroFactura($this->autogenerarNroNotaDeCredito());
                        $newVenta->setVtaDescAplicado(0);
                        $newVenta->setVtaDescuento(sfConfig::get('app_descuento'));
                        $newVenta->setVtaEfectivo($this->getTotalDevolucion());
                        $newVenta->setVtaFecha(time());
                        $newVenta->setVtaTipo(sfConfig::get('app_venta_tipo_definitiva'));
                        $newVenta->setVtaTotal($this->getTotalDevolucion());
                        $newVenta->setVtaUsuario(sfContext::getInstance()->getUser()->getGuardUser()->getId());
                        $newVenta->setVtaCliente($venta->getVtaCliente());
                        $newVenta->save();
                        //var_dump($carro);exit();
                        //Productos Facturados
                        foreach ($carro as $detalle) {
                            $cantDevuelta = $detalle["cantidad_devuelta"];
                            $cantVenta = $detalle["cantidad"];
                            $prod = $detalle["producto"];
                            $producto = ProductosPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle());
                            $precio = $producto->getPrecioVenta();
                            if ($cantDevuelta != $cantVenta) {
                                if (!empty($cantDevuelta)) {
                                    $detalleVenta = new DetalleVentas();
                                    $detalleVenta->setDetVtaArticulo($producto->getProArticulo());
                                    $detalleVenta->setDetVtaTalle($producto->getProTalle());
                                    $detalleVenta->setDetVtaVta($newVenta->getVtaId());
                                    $detalleVenta->setDetVtaCantidad($cantVenta);
                                    $detalleVenta->setDetVtaGanancia($producto->getProGanancia());
                                    $detalleVenta->setDetVtaPrecio(floatval($precio));

                                    $detalleVenta->save();
                                }
                            }
                        }
                    } else {//Devolución TOtal
                        //var_dump($venta);exit();
                        /* $detalle = $venta->getDetalleVentass();
                          $devoluciones = $venta->getDevolucioness();
                          foreach($detalle as $det){
                          $det->delete();
                          }
                          foreach($devoluciones as $dev){
                          $detalleDev = $dev->getDetalleDevolucioness();

                          foreach($detalleDev as $detDev){
                          $detDev->delete();
                          }
                          $dev->delete();
                          }
                          $venta->delete(); */
                        sfContext::getInstance()->getUser()->setFlash('notice', 'La venta se ha eliminado exitosamente.');
                    }
                } else {
                    //venta Definitiva
                    //Aumento de stock
                    foreach ($carro as $detalle) {
                        $cantDevuelta = $detalle["cantidad_devuelta"];
                        $cantVenta = $detalle["cantidad"];
                        $prod = $detalle["producto"];
                        $producto = ProductosPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle());
                        $cantActualProducto = $producto->getProCantidad();
                        $dispActualProducto = $producto->getProDisponible();
                        $producto->setProCantidad($cantActualProducto + $cantDevuelta);
                        $producto->setProDisponible($dispActualProducto + $cantDevuelta);
                        $producto->save();
                    }

                    //Aumentar Precio en caja
                    $caja = new Caja();
                    $total = $this->getTotalDevolucion();
                    $caja->almacenarCaja($total, sfConfig::get('app_caja_operacion_egreso'));

                    $userId = sfContext::getInstance()->getUser()->getGuardUser()->getId();

                    $motivo = "Devolución Venta - ID " . $venta->getVtaId();
                    $ope = sfConfig::get('app_caja_operacion_egreso');

                    //Agregar operacion
                    $operacion = new Operaciones();
                    $operacion->agregarOperacion($total, $motivo, $ope, $userId);

                    //Registro en Devoluciónes
                    $totalDevolucion = $this->getTotalDevolucion();
                    $nroNotaCredito = $this->autogenerarNroNotaDeCredito();
                    //crear devolucion
                    $devolucion = new Devoluciones();
                    $devolucion->setDevFecha(time());
                    $devolucion->setDevPrecio($totalDevolucion);
                    $devolucion->setDevNroNotaCredito($nroNotaCredito);
                    $devolucion->setDevVenta($vtaId);
                    $devolucion->save();

                    //setear productos devueltos y actualizar detalle venta
                    foreach ($carro as $detalle) {
                        $cantDevuelta = $detalle["cantidad_devuelta"];
                        $cantVenta = $detalle["cantidad"];
                        $prod = $detalle["producto"];
                        if (!empty($cantDevuelta)) {

                            //Generar nuevo detalle de devolucion
                            $ultimaDevolucion = DevolucionesPeer::obtenerUltimaDevolucion();

                            $detalleDevolucion = new DetalleDevoluciones();
                            $detalleDevolucion->setDetDevDevolucion($ultimaDevolucion->getDevId());
                            $detalleDevolucion->setDetVtaArticulo($prod->getDetVtaArticulo());
                            $detalleDevolucion->setDetVtaTalle($prod->getDetVtaTalle());
                            $detalleDevolucion->setDetVtaCantidad($cantDevuelta);
                            //$detalleDevolucion->setDetVtaPrecio($prod->getVtaPrecio());
                            $detalleDevolucion->setDetVtaPrecio($prod->getPrecioVenta());
                            $detalleDevolucion->save();

                            //Actualizar Disponibilidad de producto
                            $producto = ProductosPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle());
                            $cantActualProducto = $producto->getProCantidad();
                            $dispActualProducto = $producto->getProDisponible();
                            $producto->setProCantidad($cantActualProducto + $cantDevuelta);
                            $producto->setProDisponible($dispActualProducto + $cantDevuelta);
                            $producto->save();
                        }
                        $detalleVentaOriginal = DetalleVentasPeer::retrieveByPK($prod->getDetVtaArticulo(), $prod->getDetVtaTalle(), $vtaId);
                        if (!empty($detalleVentaOriginal)) {
                            $cant = $detalleVentaOriginal->getDetVtaCantidad();
                            if ($cantDevuelta != $cantVenta) {
                                $detalleVentaOriginal->setDetVtaCantidad($cant - $cantDevuelta);
                            } else {
                                $detalleVentaOriginal->delete();
                            }
                        }
                    }
                }
            }
            //si todo va bien guardamos los cambios
            $con->commit();
            return true;
        } catch (Exception $e) {

            // Hacemos rollback de los cambios en caso de fallo
            $con->rollBack();
            return false;
            //devolvemos el error al depurador
            //throw $e;
        }
    }

    public function esDevolucionParcial() {

        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        foreach ($carro as $detalle) {
            $cantDevuelta = $detalle["cantidad_devuelta"];
            $cantVenta = $detalle["cantidad"];
            if ($cantDevuelta != $cantVenta) {
                return true;
            }
        }
        return false;
    }

    public function getTotalDevolucion() {

        $carro = sfContext::getInstance()->getUser()->getAttribute('devolucion');

        $subtotal = 0;
        if (!empty($carro)) {
            foreach ($carro as $detalle) {

                $prod = $detalle["producto"];
                $cant = $detalle["cantidad"];
                $cantDevuelta = $detalle["cantidad_devuelta"];

                $precio = $prod->getPrecioVenta();
                $precioFinal = $precio * $cantDevuelta;

                $subtotal += $precioFinal;
            }
            return $subtotal;
        } else {
            return false;
        }
    }

    public function getTotalVenta($idVta) {

        //get venta
        $detalleVenta = DetalleVentasPeer::obtenerDetallePorIdVenta($idVta);

        //obtener total
        $subtotal = 0;
        if (!empty($detalleVenta)) {
            foreach ($detalleVenta as $linea) {

                $precio = $linea->getPrecioVenta();
                $cantidad = $linea->getDetVtaCantidad();
                $precioFinal = $precio * $cantidad;

                $subtotal += $precioFinal;
            }
            return $subtotal;
        } else {
            return false;
        }
    }

    private function autogenerarNroNotaDeCredito() {

        $devolucion = DevolucionesPeer::obtenerUltimaDevolucion();

        if (!empty($devolucion)) {
            $longitudNroNotaCred = 10;

            //Obtener nro Factura
            $nroNotaCred = $devolucion->getDevNroNotaCredito();

            //Dividir entre el nro sucursal y nro factura
            $nro = explode('-', $nroNotaCred);
            $nroCasa = $nro[0];
            $nroNota = intval($nro[1]) + 1;

            $numbersNoZero = '123456789';
            $nroDocNoZero = strpbrk($nroNota, $numbersNoZero);
            $zero = '0';
            $nroDocZeros = str_repeat($zero, $longitudNroNotaCred - strlen($nroNota));

            $nroDoc = $nroDocZeros . $nroDocNoZero;
            return $nroNotaCredito = $nroCasa . '-' . $nroDoc;
        } else {

            $nroCasa = '0000';
            $nroDoc = '0000000001';
            $nroNotaCredito = $nroCasa . '-' . $nroDoc;

            return $nroNotaCredito;
        }
    }

}

?>
